package cn.buddha.jec.flowable.handler;

import cn.buddha.jec.db.service.IFlowableInfoService;
import cn.buddha.jec.exception.TongBusinessException;
import cn.buddha.jec.exception.TongBusinessResult;
import cn.buddha.jec.exception.enums.TongExceptionEnum;
import cn.buddha.jec.flowable.constant.FlowableStatus;
import cn.buddha.jec.model.TongBaseResponse;
import cn.buddha.jec.model.TongContext;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName FlowableExceptionHandler
 * @Author 友野浩二
 * @Date 2020/4/1 22:47
 * @Description 业务逻辑处理过程中的异常处理(框架层)
 * @Version 1.0
 */
@Component
@Slf4j
public class FlowableExceptionHandler {

    /**
     * 是否开启"登记flowableInfo"开关,默认false
     */
    @Value("${flowableInfo.enable:false}")
    private Boolean enableFlowableInfo;

    /**
     * 服务流程信息 服务类
     */
    @Resource
    private IFlowableInfoService flowableInfoServiceImpl;

    public void handler(Exception e) {
        log.info("<===== preHandler starting =====>");
        // 创建自动start的计时器(记录服务流程框架异常处理的耗时时间)
        Stopwatch stopwatch = Stopwatch.createStarted();

        if (enableFlowableInfo) {
            TongBaseResponse tongBaseResponse;
            if (e instanceof TongBusinessException) {
                // 业务异常处理
                TongBusinessException tongBusinessException = (TongBusinessException) e;
                tongBaseResponse = TongBusinessResult.error(tongBusinessException.getExceptionCode(),
                        tongBusinessException.getExceptionMessage());
            } else {
                String exceptionStr = JSON.toJSONString(e);
                if (exceptionStr.length() > 2000) {
                    exceptionStr = exceptionStr.substring(0, 2000);
                }
                tongBaseResponse = TongBusinessResult.error(TongExceptionEnum.FAILED.getCode(), exceptionStr);
            }

            // 更新服务流程信息(服务流程执行异常)
            try {
                this.flowableInfoServiceImpl.updateFlowableInfo(tongBaseResponse, FlowableStatus.STATUS_EXCEPTION);
            } catch (Exception e1) {
                log.error("业务逻辑处理过程中的异常处理异常了", e1);
            }
        }

        if (log.isInfoEnabled()) {
            log.info("服务流程框架异常处理[{}]耗时[{}]", TongContext.getInstance().getReqUrl(), stopwatch.elapsed(TimeUnit.MILLISECONDS));
        }
        log.info("<===== preHandler end =====>");
    }

}
